Skip to content

feat(client): pass through sampling-mask logprobs and by-handle payload segments - #170

Open
faresobeid wants to merge 3 commits into
mainfrom
feat/top-logprobs-v2
Open

faresobeid wants to merge 3 commits into
mainfrom
feat/top-logprobs-v2

Conversation

@faresobeid

@faresobeid faresobeid commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

On top of #174's packed completion logprobs, renderers.client.generate() passes two more optional prime-rl /inference/v1/generate fields through. Both are pure pass-through: no request-side change, no parsing or validation (same as sampling_mask). Stock vLLM sends neither, and then the keys are None.

Stack

Base: #174 (perf/packed-completion-logprobs). Order: #174 -> PrimeIntellect-ai/verifiers#2778 -> prime-rl#3900; then this PR with PrimeIntellect-ai/verifiers#2756 (-> prime-rl#3794) and PrimeIntellect-ai/verifiers#2765 (-> prime-rl#3902).

Validation

  • pytest tests/test_client.py --noconftest (32 passed), ruff check, ruff format --check on renderers/client.py.

Note

Add sampling_mask_logprobs and payload to generate client result

The async generation client in client.py now reads two new fields from the generation choice and returns them. sampling_mask_logprobs carries the server's renormalized sampling-mask logprobs (prime-rl may send these with packed sampling-mask data). payload carries by-handle side-array data. Both keys are None when the choice does not provide the field.

Macroscope summarized 030b208.


Note

Medium Risk
Refactors GLM and DeepSeek V4 completion parsing and multi-turn bridging—high-impact for tool-call finish reasons and RL trajectories—while client fields are pass-through only.

Overview
Inference client now forwards optional prime-rl choice fields sampling_mask_logprobs (renormalized logprobs parallel to kept vocab ids) and payload (by-handle segments for large side arrays) through generate()’s result dict, alongside updated return-value docs.

Tagged completion parsing adds renderers/tagged.py with scan_tagged_response and separate GLM vs DeepSeek V4 state-machine grammars. GLM and DeepSeek V4 parsers in parsing.py are rewritten on top of it (per-block tool conversion, thinking_enabled, reasoning_complete). scan_reasoning treats thinking openers after leading whitespace and keeps literal delimiter spellings inside content when they are ordinary tokens, not atomic specials.

GLM / DeepSeek V4 renderers drive parsing from enable_thinking when prompt_ids is empty (documented on parse_response), and bridge_to_next_turn uses parse_response + reasoning_complete instead of ad-hoc scan_reasoning. DeepSeek DSML parsing no longer depends on a separate dsml_id token scan path.

Tests replace render→parse round-trips with reference-template continuations replayed through the real generate() HTTP client (replay.py, reference_continuations.py), add GLM/DeepSeek tagged rollout integration tests, tighten reasoning-boundary expectations for formats that reopen reasoning, and add module-scoped cache/GC teardown to cut HF memory use in CI.

Reviewed by Cursor Bugbot for commit 030b208. Bugbot is set up for automated code reviews on this repo. Configure here.

@faresobeid faresobeid changed the title feat(client): opt-in per-token top-k logprobs feat(client): pass through sampling-mask logprobs Oct 3, 2026
@faresobeid
faresobeid marked this pull request as ready for review October 3, 2026 11:52
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Oct 3, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — The shown code change is a small, backward-compatible pass-through of optional server metadata and adds no request-side or security-sensitive behavior. Unresolved review comments nevertheless identify concrete reasoning-output parsing defects in the PR head, so human review is warranted.

Notes:

  • Macroscope's correctness review did not run, so approvability was decided on eligibility alone.

You can add or adjust custom eligibility rules. Learn more.

@faresobeid
faresobeid force-pushed the feat/top-logprobs-v2 branch 3 times, most recently from 01c9cce to 1cd3446 Compare October 6, 2026 17:19
@faresobeid
faresobeid changed the base branch from main to perf/packed-completion-logprobs October 6, 2026 17:19
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Oct 6, 2026
@faresobeid
faresobeid force-pushed the perf/packed-completion-logprobs branch from e134d56 to e161362 Compare October 8, 2026 14:35
@faresobeid
faresobeid force-pushed the feat/top-logprobs-v2 branch from 1cd3446 to ea01237 Compare October 8, 2026 14:35
@macroscopeapp
macroscopeapp Bot dismissed their stale review October 12, 2026 18:47

Dismissing prior approval to re-evaluate d3a1af0

@faresobeid faresobeid changed the title feat(client): pass through sampling-mask logprobs feat(client): pass through sampling-mask logprobs and by-handle payload segments Oct 12, 2026
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Oct 12, 2026
@macroscopeapp
macroscopeapp Bot dismissed their stale review October 14, 2026 14:34

Dismissing prior approval to re-evaluate 030b208

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 030b208. Configure here.

Comment thread renderers/reasoning.py
close == -1, text[start : close if close != -1 else len(text)], by_tool
close == -1,
text[start : close if close != -1 else len(text)].replace(open_marker, ""),
by_tool,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reasoning text drops think markers

Medium Severity

scan_reasoning already skips the leading <think> opener, then deletes every later open_id and every <think> substring before decoding what remains. Reasoning that mentions the tag, or a truncated </think>, loses those characters, and neighboring tokens can merge into different text.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 030b208. Configure here.

Comment thread renderers/parsing.py
(reasoning or "").rstrip()
if parsed.boundary.is_open
else (reasoning or "").rstrip() or None
),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DeepSeek reasoning boundary whitespace stripped

Medium Severity

parse_deepseek_v4 always rstrips reasoning and turns whitespace-only content into "". The newline the model emits before </think>, and a content channel that is only that separator, disappear from the parsed message.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 030b208. Configure here.

@faresobeid
faresobeid changed the base branch from perf/packed-completion-logprobs to main October 14, 2026 17:04

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant